package org.example.common.util;


import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class CompressUtil {
    /**
     * 生成压缩文件
     * @param srcFilePaths 需要压缩的文件的路径（绝对路径或相对路径）
     * @param zipFilePath 压缩完后存放的文件的路径
     * @param keepDirStructure 是否保持文件目录结构
     */
    public static void compress(List<String> srcFilePaths, String zipFilePath, Boolean keepDirStructure) {
        byte[] buf = new byte[1024];//创建缓冲区，减少io操作
        File zipFile = new File(zipFilePath);//获得包装路径（抽象路径），可以更好查找，以及创建

        // 确保目标ZIP文件的父目录存在
        if (!zipFile.getParentFile().exists()) {
            zipFile.getParentFile().mkdirs(); // 创建多级父目录
        }

        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()))) {
            for (String srcFilePath : srcFilePaths) {
                // 跳过空路径
                if (StringUtils.isEmpty(srcFilePath)) {
                    continue;
                }

                File sourceFile = new File(srcFilePath);
                // 检查源文件是否存在且是文件（不是目录）
                if (!sourceFile.exists() || !sourceFile.isFile()) {
                    System.out.println("跳过无效文件/目录：" + srcFilePath);
                    continue;
                }

                // 使用try-with-resources自动关闭输入流
                try (FileInputStream fis = new FileInputStream(sourceFile)) {
                    String entryName;
                    if (keepDirStructure != null && keepDirStructure) {
                        // 保留目录结构：使用源文件的相对路径（这里简化处理，实际可根据需求调整为相对路径）
                        // 若需要严格相对路径，可传入基础目录，计算与基础目录的相对路径
                        entryName = sourceFile.getPath();
                    } else {
                        // 不保留目录结构：仅使用文件名作为条目名称（平级存放）
                        entryName = sourceFile.getName();
                    }

                    // 创建ZIP条目（文件类型，不加/）
                    zos.putNextEntry(new ZipEntry(entryName));

                    // 写入文件内容
                    int len;
                    while ((len = fis.read(buf)) > 0) {
                        zos.write(buf, 0, len);
                    }

                    // 关闭当前条目（必须，确保条目信息完整）
                    zos.closeEntry();
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("文件压缩失败：" + e.getMessage(), e);
        }
    }


    /**
     * 下载zip文件
     *
     * @param response 返回体
     * @param zipName  浏览器header中zip名称
     * @param zipFile  zipFile文件
     */
    public static void downloadZip(HttpServletResponse response, String zipName, File zipFile) {
        //下载文件
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment;FileName=" + zipName);
            ServletOutputStream out = response.getOutputStream();
            int len = 0;
            byte[] buffer = new byte[1024];
            FileInputStream fis = new FileInputStream(zipFile);
            while ((len = fis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
                out.flush();
            }
            out.close();
            fis.close();
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 下载文件 支持多个下载
     * 格式 zip包
     */
//    @RequestMapping("/downloadZip")
//    public void download(int id, HttpServletResponse response) {
//        downloadZip(id, response);
//    }
//
//    public void downloadZip(int id, HttpServletResponse response) {
//        List<TFile> tFiles = fileService.queryFilesByRId(id);
//        if (ListUtils.isNotBlank(tFiles)) {
//            String zipName = "ZXJD_" + ((int) (Math.random() * 10000)) + ".zip";
//            String zipPath = basePath + zipName;
//            if (active.equals("dev")) {
//                CompressUtil.compress(tFiles, zipPath, false);
//            } else {
//                CompressUtil.compress(tFiles, zipPath, fileService);
//            }
//
//            File pocZipFile = new File(zipPath);
//            CompressUtil.downloadZip(response, zipName, pocZipFile);
//        }
//    }
}
